#ifdef __GNUC__
#include <stdio.h>
#include <string.h>
#include <winsock2.h>
#endif
#ifdef _MSC_VER
#include <STDIO.H>
#include <STRING.H>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
//#pragma comment(lib, "WSOCK32.LIB")
#endif


int main(int argc, char *argv[])
{
    // 0. 初始化网络环境
    char enable_reuseaddr = 1;
    int select_ret;
    WSADATA wsaData;
    SOCKET sockfd;
    SOCKADDR_IN addr = {0};

    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    {
        printf("初始化Winsock失败\n");
        return -1;
    }

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (INVALID_SOCKET == sockfd)
    {
        printf("创建服务端句柄失败\n");
        WSACleanup();
        return -1;
    }

    // 2. 绑定端口号和IP地址
    addr.sin_family = AF_INET;
    addr.sin_port = htons(11223);// 端口号  host to net short
    //addr.sin_addr.S_un.S_addr指明了服务端所在的主机位置。
    //addr.sin_addr.S_un.S_addr应当设置为服务端所在的IP地址
    //addr.sin_addr.S_un.S_addr = INADDR_ANY; // IP地址 所有IP都行
    //addr.sin_addr.S_un.S_addr = inet_addr("192.168.1.4"); // 特定IP地址
    addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");   //本机地址
    if (bind(sockfd, (struct sockaddr*)&addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR){
        closesocket(sockfd);
        WSACleanup();
        return -1;
    }

    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enable_reuseaddr, sizeof(enable_reuseaddr));

    struct timeval tval;
    tval.tv_sec = 0;
    tval.tv_usec = 50000;

    int pathlen = 1500;
    int rflen = 0;
    char *srcpath = (char*)malloc(pathlen);


    int rbufsize = 1400;
    int rlen = 0;
    char *rbuf = (char*)malloc(rbufsize);

    while (1) {
        struct sockaddr fromh;
        int froml = sizeof(fromh);

//        fd_set fdset;
//        FD_ZERO(&fdset);
//        FD_SET(sockfd, &fdset);

//        select_ret = select(sockfd + 1, &fdset, NULL, NULL, &tval);
//        if(select_ret < 0){
//            printf("select error\n");
//            continue;
//        }

//        if(select_ret == 0){
//            printf("select timeout\n");
//            continue;
//        }

//        if(!FD_ISSET(sockfd, &fdset)){
//            printf("sockfd is not in fdset\n");
//            continue;
//        }

        rflen = recvfrom(sockfd, srcpath, pathlen, 0, &fromh, &froml);

        printf("fd is %d, rflen is %d\n", sockfd, rflen);

        srcpath[rflen] = 0;
        if(!memcmp(srcpath, "@hello", 6)){
            char *echo = "@world";
            sendto(sockfd, echo, strlen(echo), 0, &fromh, froml);
            continue;
        }
        if(!memcmp(srcpath, "@exit", 5)){
            break;
        }
        {

            FILE *f = fopen(srcpath, "r");
            if(!f){
                char *echo = "@error";
                sendto(sockfd, echo, strlen(echo), 0, &fromh, froml);
                continue;
            }
            char *start = "@start";
            char *end = "@end";


            sendto(sockfd, start, strlen(start), 0, &fromh, froml);
            while(!feof(f)){
                rlen = fread(rbuf, 1, rbufsize, f);
                sendto(sockfd, rbuf, rlen, 0, &fromh, froml);
            }
            fclose(f);
            sendto(sockfd, end, strlen(end), 0, &fromh, froml);

            remove(srcpath);
        }
    }

    free(srcpath);
    free(rbuf);


    // 主循环结束后，关闭服务端套接字
    closesocket(sockfd);
    // 清理Winsock资源
    WSACleanup();
    printf("资源已清理\n");
    return 0;
}
